<template>
    <div>
        <el-dialog
            :visible.sync="detailDialog"
            :modal="false"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
            :fullscreen="true"
            :before-close="closeDialog"
        >
            <template slot="title">
                <div class="title-icon"></div>
                <span class="title-text">{{ getTitle() || '--' }}</span>
            </template>

            <div class="content table-menu-box" v-if="['用户访问流量', '菜单访问流量'].includes(info.title)">
                <el-card v-if="info.title == '用户访问流量'">
                    <!-- 用户访问流量(用户进来调菜单) -->
                    <div class="title-center">
                        <div class="total-num">
                            {{ `总访问菜单数：${menuTotalVisitorsNum} ` }}
                        </div>
                        <div class="total-num">
                            {{ `总访问次数：${menuTotalVisitsNum} ` }}
                        </div>
                    </div>
                    <div style="height: 100%">
                        <BarChart ref="detail" chartName="menu" :data="menuChartData" :isDetail="true" />
                    </div>
                </el-card>
                <el-card v-else-if="info.title == '菜单访问流量'">
                    <!--菜单访问流量(菜单进来调用户) -->
                    <div class="title-center">
                        <div class="total-num">
                            {{ `总访问用户数：${userTotalVisitorsNum} ` }}
                        </div>
                        <div class="total-num">
                            {{ `总访问次数：${userTotalVisitsNum} ` }}
                        </div>
                    </div>
                    <div style="height: 100%">
                        <BarChart ref="detail" chartName="user" :data="userChartData" :isDetail="true" />
                    </div>
                </el-card>
            </div>

            <div
                class="table-content"
                :style="{ height: ['系统访问走势', '日均访问流量'].includes(info.title) ? 'calc(100vh - 180px)' : 'calc(78vh - 175px)' }"
            >
                <vxe-table
                    border
                    :cell-style="getCellStyle"
                    :row-config="{ isHover: true }"
                    :sort-config="{
                        defaultSort: { field: sortProp, order: sortOrder, orders: ['desc', 'asc', null] },
                        remote: true,
                    }"
                    stripe
                    :filter-config="{ remote: true }"
                    @filter-change="handleFilter"
                    @sort-change="handleSort"
                    :data="tableData"
                    show-header-overflow
                    class="table"
                    header-align="center"
                    :key="columnsKey"
                    height="100%"
                    auto-resize
                    :tooltip-config="{ enterable: true }"
                    v-loading="loading"
                >
                    <vxe-column
                        v-for="item in columns"
                        :field="item.val"
                        :title="item.name"
                        :key="item.val"
                        :filters="item.filters"
                        :min-width="item.minWidth || '90px'"
                        show-overflow="tooltip"
                        sortable
                    >
                        <template #filter="{ $panel, column }" v-if="!checkFiltersParams.includes(item.val)">
                            <!-- <div v-if="item.val == 'serialNo'">
                                <el-input-number
                                    class="my-input"
                                    size="small"
                                    v-model="option.data"
                                    v-for="(option, index) in column.filters"
                                    :key="index"
                                    controls-position="right"
                                    @input="$panel.changeOption($event, !!option.data, option)"
                                />
                            </div>
                            <div v-else> -->
                            <div>
                                <el-input
                                    ref="searchInput"
                                    class="my-input"
                                    type="type"
                                    v-for="(option, index) in column.filters"
                                    :key="index"
                                    v-model="option.data"
                                    @input="handleFilterInput($event, $panel, option, column)"
                                />
                            </div>
                        </template>
                        <template slot-scope="scope">
                            <span v-if="item.type == 'func'">
                                {{ item.funcBody(scope.row[item.val], scope.row) || '--' }}
                            </span>
                            <span v-else :style="getStyle(item.val, scope.row[item.val])">
                                {{
                                    scope.row[item.val] === 0 || (scope.row[item.val] && (scope.row[item.val] + '').trim())
                                        ? scope.row[item.val]
                                        : '--'
                                }}
                            </span>
                        </template>
                    </vxe-column>
                </vxe-table>
            </div>
            <RiskPagination :paging="paging" @page-change="pageChange"></RiskPagination>
        </el-dialog>
    </div>
</template>

<script lang="ts">
import RiskPagination from '@/common/components/risk-pagination.vue';
import RiskTable from '@/common/components/risk-table.vue';
import { dateFormat, timeFormat } from '@/utils/tools';
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import {
    queryUserBehaviorMenuSelectByRequest,
    queryUserBehaviorMenuTrend,
    queryUserBehaviorTrendDetail,
    queryUserBehaviorUserTrend,
} from '../api/user-behavior-analysis';
import moment from 'moment';
export interface pages {
    total?: number;
    pageSize?: number;
    currentPage?: number;
}
@Component({
    name: 'TableDetail',
    components: { RiskTable, RiskPagination, BarChart: () => import('./bar-chart.vue') },
})
export default class TableDetail extends Vue {
    @Prop() detailDialog: boolean;
    @Prop() info: any;

    dateFormat = dateFormat;
    timeFormat = timeFormat;
    columnsKey: number = 1;
    menuOptions: any[] = [];
    columns: any[] = [
        { name: '序号', val: 'serialNo', sortable: true, search: true, filters: [{ data: '' }] },
        { name: '操作员', val: 'operateUser', sortable: true, search: true, filters: [{ data: '' }] },
        {
            name: '操作菜单',
            val: 'resourceName',
            sortable: true,
            search: true,
            filters: this.menuOptions,
            type: 'func',
            funcBody: (value, row) => row.resourceParentName + '-' + row.resourceName,
        },
        { name: '操作事件', val: 'operateRemark', sortable: true, search: true, filters: [{ data: '' }] },
        { name: '请求地址', val: 'requestUrl', sortable: true, search: true, filters: [{ data: '' }] },
        { name: '浏览器', val: 'browser', sortable: true, search: true, filters: [{ data: '' }] },
        { name: 'IP地址', val: 'host', sortable: true, search: true, filters: [{ data: '' }] },
        {
            name: '操作时间',
            val: 'operateDate',
            sortable: true,
            type: 'func',
            funcBody: (value, row) => dateFormat(row.operateDate) + ' ' + timeFormat(row.operateTime),
        },

        {
            name: '调用结果',
            val: 'result',
            sortable: true,
            search: true,
            filters: [
                { label: '成功', value: '成功' },
                { label: '失败', value: '失败' },
            ],
        },
        { name: '调用耗时(ms)', val: 'time', sortable: true },
        {
            name: '请求方式',
            val: 'method',
            sortable: true,
            search: true,
            filters: [
                { label: 'GET', value: 'GET' },
                { label: 'PUT', value: 'PUT' },
                { label: 'POST', value: 'POST' },
                { label: 'DELETE', value: 'DELETE' },
            ],
        },
    ];

    sortProp: string = '';
    sortOrder: string = 'desc'; // 排序方式
    tableData: any[] = [];
    loading: boolean = false;
    checkFiltersParams = ['monitorResultType', 'result', 'method', 'resourceName']; // 注意添加 todo
    // 分页
    paging: pages = {
        total: 0,
        pageSize: 25,
        currentPage: 1,
    };

    // 查询表单
    queryParams = {
        startDate: '',
        startTime: '',
        endDate: '',
        endTime: '',
        browser: '',
        host: '',
        methods: [],
        // method: '',
        operateNo: '',
        // operateUser: '',
        operateRemark: '',
        requestUrl: '',
        resourceCodes: [], // 菜单编码
        // resourceCode: '',
        results: [],
        // result: '',
        serialNo: '',
        paging: {
            currentPage: 1,
            pageSize: 25,
        },
        sort: {
            field: '',
            order: '',
        },
    };
    iconDom = null;
    userChartData: any = {
        name: '',
        data: [],
        xData: [],
        title: '用户访问流量1',
    };
    userTotalVisitorsNum: number = 0;
    userTotalVisitsNum: number = 0;
    menuTotalVisitorsNum: number = 0;
    menuTotalVisitsNum: number = 0;

    // 菜单数据
    menuChartData: any = {
        data: [],
        xData: [],
        title: '菜单访问流量1',
    };

    @Watch('info', { immediate: true, deep: true })
    async onWatchInfo() {
        const info = this.info;
        this.queryParams = {
            ...this.queryParams,
            startDate: info.startDate,
            startTime: info.startTime,
            endDate: info.endDate,
            endTime: info.endTime,
            operateNo: info.operateNo,
            resourceCodes: info.resourceCode ? [info.resourceCode] : [],
            paging: {
                pageSize: this.paging.pageSize,
                currentPage: this.paging.currentPage,
            },
            sort: {
                field: '',
                order: '',
            },
        };
        if (!['系统访问走势', '日均访问流量'].includes(this.info.title)) {
            this.getChartData();
        }
        await this.getMenuOptions();
        this.changeTable();
        this.getTableData();
    }

    async mounted() {
        if (!['系统访问走势', '日均访问流量'].includes(this.info.title)) {
            window.addEventListener('resize', this.screenAdapter);
            this.screenAdapter();
        }
    }

    screenAdapter() {
        const titleFontSize = ((this.$refs['detail'] as any).offsetWidth / 100) * 5.6;
        // 分辨率变化图表配置
        const adapterOption = {
            axisLabel: {
                textStyle: {
                    fontSize: titleFontSize,
                },
            },
            // 柱状条目
            series: [],
        };

        const ele = (this.$refs['detail'] as any).chartInstance;
        ele.setOption(adapterOption);
        ele.resize();
    }

    // 图表数据
    getChartData() {
        if (this.info.resourceCode) {
            // 菜单进来调用户
            queryUserBehaviorUserTrend({ startDate: this.info.startDate, endDate: this.info.endDate, resourceCode: this.info.resourceCode })
                .then((res: any) => {
                    const actualData = res.userBarChart;
                    this.userChartData.data = actualData.data[0].data;
                    this.userChartData.name = actualData.data[0].name;
                    this.userChartData.xData = actualData.xData;
                    this.userTotalVisitorsNum = res.totalVisitorsNum;
                    this.userTotalVisitsNum = res.totalVisitsNum;
                })
                .catch(() => {});
        } else if (this.info.operateNo) {
            // 用户进来调菜单
            queryUserBehaviorMenuTrend({
                startDate: this.info.startDate,
                endDate: this.info.endDate,
                operateNo: this.info.operateNo,
            })
                .then((res: any) => {
                    const obj = res.menuBarChart?.data[0];
                    this.menuChartData.data = obj?.data;
                    this.menuChartData.name = obj?.name;
                    this.menuChartData.xData = res?.menuBarChart.xData;
                    this.menuTotalVisitorsNum = res.totalAccessMenuNum;
                    this.menuTotalVisitsNum = res.totalVisitsNum;
                    console.log(this.menuChartData, 'menuChartData');
                })
                .catch(() => {});
        }
    }

    // 改变筛选按钮
    changeTable() {
        let indexArr = [2, 7, 8]; // 注意添加
        this.$nextTick(() => {
            if (!this.iconDom) {
                let dom = document.querySelector('.table-content');
                this.iconDom = dom.querySelectorAll('.vxe-icon--funnel');
                for (let i = 0; i < this.iconDom.length; i++) {
                    if (!indexArr.includes(i)) {
                        this.iconDom[i].className = 'vxe-filter--btn el-icon-search';
                    }
                }
            }
        });
    }

    // 获取表格数据
    getTableData() {
        this.loading = true;
        queryUserBehaviorTrendDetail(this.queryParams)
            .then((res: any) => {
                this.tableData = res.logPageResponse.list;
                this.paging.total = res.logPageResponse.total;
                this.loading = false;
            })
            .catch(() => {
                this.loading = false;
            });
    }

    /**
     * 表头筛选
     */
    async handleFilter(obj) {
        this.paging.currentPage = 1;
        this.queryParams.paging = {
            pageSize: this.paging.pageSize,
            currentPage: 1,
        };

        const field = obj.field;
        if (this.checkFiltersParams.includes(field)) {
            if (field == 'resourceName') {
                this.queryParams['resourceCodes'] = [];
            }
            this.queryParams[field + 's'] = [];
        } else {
            this.queryParams[field] = '';
        }
        let filterList = obj.filterList;
        if (filterList.length) {
            filterList.forEach(ele => {
                let property = ele.property;
                if (this.checkFiltersParams.includes(property)) {
                    if (field == 'resourceName') {
                        this.queryParams['resourceCodes'] = ele.values;
                    }
                    this.queryParams[ele.property + 's'] = ele.values;
                } else {
                    this.queryParams[ele.property] = ele?.datas[0] || '';
                }
            });
        }

        this.getTableData();
    }

    // 处理输入框
    handleFilterInput($event, $panel, option, column) {
        if (column.property == 'serialNo') {
            option.data = option.data.replace(/[^0-9]/g, '');
            console.log(option.data, 'lllll');
        }
        $panel.changeOption($event, !!option.data, option);
    }
    // 获取菜单筛选框数据
    async getMenuOptions() {
        const arr = await queryUserBehaviorMenuSelectByRequest(this.queryParams);
        const menuOptions = arr.map(item => {
            return { label: item.dictKeyName, value: item.dictKey };
        });
        this.columns = this.columns.map(item => {
            if (item.val == 'resourceName') {
                item.filters = menuOptions;
            }
            return item;
        });
        this.columnsKey++;
        console.log(menuOptions, 'menuOptions');
    }

    /**
     * 表头排序
     */
    handleSort(column: any) {
        this.paging.currentPage = 1;
        this.queryParams.paging = {
            currentPage: 1,
            pageSize: this.paging.pageSize,
        };
        this.sortProp = column.property;
        this.sortOrder = column.order;
        this.queryParams.sort = {
            field: this.sortProp,
            order: this.sortOrder,
        };
        this.getTableData();
    }

    // 分页回调
    pageChange() {
        this.queryParams.paging.currentPage = this.paging.currentPage;
        this.queryParams.paging.pageSize = this.paging.pageSize;
        this.getTableData();
    }

    // 关闭窗口
    closeDialog() {
        this.$emit('closeDialog');
    }

    // 对象转数组(仅用于过滤)
    changeObjToArr(obj) {
        let data = [];
        for (let key in obj) {
            data.push({ label: obj[key], value: key });
        }
        return data;
    }

    getStyle(val: string, value: string) {
        let color = '';
        if (val == 'monitorResultType') {
            color = value == '0' ? 'green' : value == '1' ? 'red' : '';
        } else if (val == 'result') {
            color = value == '成功' ? 'green' : value == '失败' ? 'red' : '';
        }
        return { color: color };
    }

    // 对齐方式
    getCellStyle({ column }) {
        let value = 'text-align:left';
        let obj = this.columns.find(item => item.val == column.property);
        if (obj) {
            value = 'text-align: ' + (obj.align || 'left');
        }
        return value;
    }

    closeTooltip() {
        const dom = document.querySelector('.vxe-table--tooltip-wrapper');
        if (dom) {
            dom.remove();
        }
    }

    // 显示标题
    getTitle() {
        const title = this.info.title;
        let retTitle = title + '详情';
        if (title == '菜单访问流量') {
            retTitle += `(${this.info.name.split('-')[1]})`;
        } else if (title == '用户访问流量') {
            retTitle += `(${this.info.name.split(':')[1]})`;
        } else if (title == '日均访问流量') {
            let s = this.info.showStartTime;
            let e = this.info.showEndTime;
            s = moment(s, 'HHmm').format('HH:mm');
            e = moment(e, 'HHmm').format('HH:mm');
            retTitle += `(${s}-${e})`;
        }
        return retTitle;
    }
}
</script>

<style lang="scss" scoped>
@import '@/pages/report/styles/common';
.my-input {
    margin: 10px;
    width: 150px;
}
.title-icon {
    width: 20px;
    height: 20px;
    display: inline-block;
    border: 4px solid #2288ff;
    border-radius: 50%;
    margin-right: 4px;
}
.title-text {
    display: inline-block;
    font-size: 16px;
    font-weight: 900;
}

/deep/ .el-dialog {
    .el-dialog__header {
        display: flex;
        align-items: center;
        background-color: #fff;
        border-bottom: 1px solid #ccc;

        .el-dialog__title {
            font-size: 16px;
            color: #333333;
        }
        .el-dialog__headerbtn .el-dialog__close {
            font-size: 24px;
            color: #515151;
        }
    }
    .el-dialog__body {
        max-height: 100%;
    }
}
/deep/ .el-dialog__wrapper {
    overflow: hidden;
}

.table /deep/ .vxe-cell .vxe-cell--title {
    font-size: 14px;
}
/deep/.c--tooltip {
    max-height: 50px !important;
    overflow: scroll;
}
// 同主页中的content
.content {
    margin-bottom: 10px;
    .title-center {
        display: flex;
        align-items: center;
        position: absolute;
        right: calc(50% - 153px);
        .total-num {
            margin-right: 20px;
            color: #fff;
            background-color: #578bec;
            padding: 5px 15px;
            font-size: 14px;
            background: url('../images/item-monitor-total.png');
            background-size: 100% 30px;
            background-repeat: no-repeat;
        }
    }

    // /deep/ .el-card {
    //     height: 100%;
    //     .el-card__body {
    //         padding: 10px;
    //         height: 100%;
    //         position: relative;
    //     }
    // }
}

.table-menu-box {
    height: 23vh;
    min-height: 200px;
}
</style>
<style lang="scss">
.vxe-table--tooltip-wrapper .vxe-table--tooltip-content {
    max-height: 200px;
    overflow: auto;
    z-index: 2200;
}
</style>
